﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using AMM.Business;
using AMM.Business.Store;
using AMM.CustomWinControls;
using AMM.Model;
using AMM.Model.Store;
using AMM.UserControls;
using FarPoint.Win.Spread;
using FarPoint.Win.Spread.CellType;
using System.Drawing;
using FarPoint.Excel;
using System.IO;

namespace AMM.Forms.Store {
    public partial class FrmQuotation : FrmQuotationBase {

        private int _pageIndex;
        private QuotationSearchModel _searchModel;
        private QuotationProcessor _quotationProcessor;
        private List<QuotationViewModel> _quotationList;

        #region Override

        protected override string FunctionCode {
            get { return "AMM1402"; }
        }

        protected override BaseSearchControl SearchControl {
            get { return new QuotationSearchControl(); }
        }

        protected override void Add() {
            base.Add();
            this.ResetForms();
            this.ShowEditForm("新增", new Quotation() { IsMultiple = false, ClassStatus = ClassStatus.Added });
        }

        protected override void Amend() {
            List<QuotationViewModel> selectedList = this.dgvQuotationList.GetSelectedRows<QuotationViewModel>();
            if (selectedList.Count > 1) { this.OnlySelectSingleRecord(); return; }
            if (selectedList.Count == 0) { this.ShouldSelectSingleRecord(); return; }
            Quotation quotation = this._quotationProcessor.FetchQuotationById(selectedList[0].Key);
            quotation.ClassStatus = ClassStatus.Updated;
            if ((AuditStatus)quotation.Status == AuditStatus.Audited) {
                this.ShowInfo("审核的订单不能被修改！");
                return;
            }
            this.ShowEditForm("修改", quotation);
            base.Amend();
        }

        protected override void Save() {
            base.Save();
        }

        protected override void Delete() {
            base.Delete();
            List<QuotationViewModel> selectedList = this.dgvQuotationList.GetSelectedRows<QuotationViewModel>();
            if (selectedList.Count == 0) { this.ShouldSelectSingleRecord(); return; }
            this.CreateNewThread(() => {
                this.PreventCancel = true;
                this._quotationProcessor.Delete(selectedList.Select(x => x.Key).ToArray());
                this.MDIParent.SetStatusInformation("删除成功");
            }, () => {
                this.ResetForms();
                this.PreventCancel = false;
            });
        }

        protected override void Audit() {
            List<QuotationViewModel> selectedList = this.dgvQuotationList.GetSelectedRows<QuotationViewModel>();
            if (selectedList.Count > 1) { this.OnlySelectSingleRecord(); return; }
            if (selectedList.Count == 0) { this.ShouldSelectSingleRecord(); return; }
            this.CreateNewThread(() => {
                this.PreventCancel = true;
                string resultMsg = string.Empty;
                Quotation quotation = this._quotationProcessor.FetchQuotationById(selectedList[0].Key);
                if (quotation.Status == (int)AuditStatus.Audited) {
                    if (this.ShowQuestion("订单已经通过审核，确定将取消审核状态！") == DialogResult.No) { return; }
                    quotation.Status = (int)AuditStatus.Waiting;
                    resultMsg = "取消审核成功";
                }
                else {
                    quotation.Status = (int)AuditStatus.Audited;
                    resultMsg = "审核成功";
                }
                quotation.AuditedBy = LoginUserName;
                this._quotationProcessor.Audit(quotation);
                this.MDIParent.SetStatusInformation(resultMsg);
            }, () => {
                this.ResetForms();
                this.PreventCancel = false;
                base.Audit();
            });
        }

        protected override void Search(object sender, FrmSearch.SearchArgs e) {
            this.CreateNewThread(() => {
                if (e.IsRevert) {
                    this._searchModel = new QuotationSearchModel();
                }
                else {
                    this._searchModel = (QuotationSearchModel)e.SearchModel;
                }
            }, () => {
                this.BindQuotationList();
            });
        }

        protected override void Export() {
            base.Export();

            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog(this) == DialogResult.OK) {
                this.CreateNewThread(() => {
                    List<Quotation> qList = new QuotationProcessor().FetchQuotationList();
                    FpSpread fs = new FpSpread();
                    MemoryStream ms = new MemoryStream(AMM.Properties.Resources.Quotation);
                    fs.OpenExcel(ms);
                    SheetView sv = fs.Sheets[0];

                    int i = 1;
                    qList.ForEach(x => {
                        sv.SetValue(i, 0, x.QuotationId);
                        sv.SetValue(i, 1, x.Material.Code);
                        sv.SetValue(i, 2, x.Material.Name);
                        sv.SetValue(i, 3, x.Material.Remarks);
                        sv.SetValue(i, 4, x.IsMultiple ? "是" : string.Empty);
                        sv.SetValue(i, 5, x.Price);
                        sv.SetValue(i, 6, x.PriceThresholdValue);
                        sv.SetValue(i, 7, x.PriceGreaterThan);
                        sv.SetValue(i, 8, x.ProcurementCycle);
                        sv.SetValue(i, 9, x.PreProcurementCycle);
                        sv.SetValue(i, 10, x.MinimumPackage);
                        sv.SetValue(i, 11, x.MinimumProcurement);
                        sv.SetValue(i++, 12, x.Basic.Name);

                        this.UpdateProcessBar(i + 1, qList.Count);
                    });
                    fs.SaveExcel(string.Format(@"{0}\物料报价单.xlsx", fbd.SelectedPath), ExcelSaveFlags.UseOOXMLFormat);
                }, () => {
                    this.ShowInfo("导出操作成功！");
                });
            }
        }

        protected override void UpdateProcessBar(int value, int totalValue) {
            if (this.InvokeRequired) {
                this.Invoke(new ThreadDelegate<int, int>(this.UpdateProcessBar), value, totalValue);
            }
            else {
                int val = (int)(value * (100.0000M / totalValue));
                this.progressBar1.Visible = true;
                this.progressBar1.Value = val > this.progressBar1.Maximum ? this.progressBar1.Maximum : val;
            }
        }

        protected override void Import() {
            base.Import();
            OpenFileDialog ofd = new OpenFileDialog() {
                Multiselect = false,
                DefaultExt = ".xlsx",
                Filter = "Excel File|*.xlsx"
            };
            if (ofd.ShowDialog(this) == DialogResult.OK) {
                this.CreateNewThread(() => {
                    FpSpread fs = new FpSpread();
                    fs.OpenExcel(ofd.FileName, ExcelOpenFlags.DataOnly);
                    SheetView sv = fs.Sheets[0];

                    foreach (Row row in sv.Rows) {
                        int rowIndex = row.Index;
                        if (rowIndex == 0) { continue; }
                        int key = Convert.ToInt32(sv.GetValue(rowIndex, 0));
                        bool isMultiple = !(sv.GetValue(rowIndex, 4) == null || string.IsNullOrEmpty(sv.GetValue(rowIndex, 4).ToString()));
                        decimal price = Convert.ToDecimal(sv.GetValue(rowIndex, 5));
                        decimal priceThresholdValue = Convert.ToDecimal(sv.GetValue(rowIndex, 6));
                        decimal priceGreaterThan = Convert.ToDecimal(sv.GetValue(rowIndex, 7));
                        int procurementCycle = Convert.ToInt32(sv.GetValue(rowIndex, 8));
                        int preProcurementCycle = Convert.ToInt32(sv.GetValue(rowIndex, 9));
                        int minimumPackage = Convert.ToInt32(sv.GetValue(rowIndex, 10));
                        int minimumProcurement = Convert.ToInt32(sv.GetValue(rowIndex, 11));

                        Quotation q = this._quotationProcessor.FetchQuotationById(key);
                        if (q == null) { break; }
                        q.IsMultiple = isMultiple;
                        q.Price = price;
                        q.PriceThresholdValue = priceThresholdValue;
                        q.PriceGreaterThan = priceGreaterThan;
                        q.ProcurementCycle = procurementCycle;
                        q.PreProcurementCycle = preProcurementCycle;
                        q.MinimumPackage = minimumPackage;
                        q.MinimumProcurement = minimumProcurement;

                        this._quotationProcessor.Update(q);
                    }
                }, () => {
                    this.BindQuotationList();
                    this.ShowInfo("导入操作成功！");
                });
            }
        }

        #endregion

        public FrmQuotation() {
            this.InitializeComponent();

            this.dgvQuotationList.DataGridViewModelType = typeof(QuotationViewModel);
        }

        #region Private methods

        private bool frmEdit_Edit(object sender, FrmEdit.EditArgs e) {
            bool resultFlag = false;
            this.PreventCancel = true;
            Quotation quotation = (Quotation)e.EditModel;
            this.CreateNewThread(() => {
                if (quotation.ClassStatus == ClassStatus.Added) {
                    quotation.CreatedBy = LoginUserName;
                    this._quotationProcessor.Insert(quotation);
                }
                else {
                    quotation.ModifiedBy = LoginUserName;
                    this._quotationProcessor.Update(quotation);
                }
                resultFlag = true;
            }, () => {
                this.ResetForms();
                this.PreventCancel = false;
                if (resultFlag) {
                    this.MDIParent.SetStatusInformation("保存成功");
                    this.FormEdit.Close();
                }
            });
            this.Save();
            return true;
        }

        private void ResetForms() {
            this.BindQuotationList();
        }

        private void BindQuotationList() {
            this.CreateNewThread(() => {
                this._quotationList = this._quotationProcessor.FetchQuotationViewModelList(this._searchModel, this._pageIndex);
            }, () => {
                this.dgvQuotationList.DataSource = new SortableBindingList<QuotationViewModel>(this._quotationList);
                this.pceList.Records = this._searchModel.Records;
                this.pceList.DataBind();
            });
        }

        private void ShowEditForm(string title, Quotation quotation) {
            QuotationEditControl editControl = new QuotationEditControl();
            this.FormEdit = new FrmEdit();
            editControl.BaseEditModel = quotation;
            editControl.ValidatorForEdit = this.FormEdit.validatorForEdit;
            this.FormEdit.Controls.Add(editControl);
            this.FormEdit.Edit += new FrmEdit.EditEventHandler(frmEdit_Edit);
            this.FormEdit.Text = string.Format("{0}{1}", title, this.Text);
            FrmEntry.LoadAndRunDialog(this.FormEdit);
        }

        #endregion

        private void FrmQuotation_Load(object sender, EventArgs e) {
            this.CreateNewThread(() => {
                this.PreventCancel = true;
                this._quotationProcessor = new QuotationProcessor(this.pceList.PageSize);
                this._searchModel = new QuotationSearchModel();
                this._pageIndex = 1;
            }, () => {
                this.WindowState = FormWindowState.Maximized;
                this.BindQuotationList();
                this.PreventCancel = false;
            });
        }

        private void pceList_Paging(object sender, PaginationArgs e) {
            this._pageIndex = e.PageIndex;
            this.BindQuotationList();
        }

    }
}
